#ifndef IMAGECACHEMANAGER_H
#define IMAGECACHEMANAGER_H

#include <QObject>
#include <QMap>
#include <QImage>
#include <QString>
#include <QUuid>
#include <QVariantMap>
#include <QQueue>

#include "ImageLoader.h"
#include "ImageSaver.h"
#include "ImageCacheItem.h"


/**
 * @brief 图像缓存管理器类
 * 负责管理图像的原始图像、处理后图像、转换比例和处理参数
 */
class ImageCacheManager : public QObject
{
    Q_OBJECT
public:
    explicit ImageCacheManager(QObject *parent = nullptr);
    ~ImageCacheManager();

    /**
     * @brief 添加图像到缓存
     * @param originalImagePath 原始图像文件路径
     * @return 图像的唯一标识GUID
     */
    QString addImageToCache(const QString &originalImagePath);

    /**
     * @brief 添加图像到缓存
     * @param originalImage 原始图像
     * @return 图像的唯一标识GUID
     */
    QString addImageToCache(const QImage &originalImage);
    /**
     * @brief 直接添加图像到缓存
     * @param imageGuid 图像的唯一标识GUID
     * @param originalImage 原始图像对象
     * @return 是否添加成功
     */
    bool addImageToCache(const QString& imageGuid,const QImage &originalImage);

    /**
     * @brief 获取原始图像
     * @param imageGuid 图像唯一标识
     * @return 原始图像
     */
    QImage getOriginalImage(const QString &imageGuid) const;

    /**
     * @brief 获取处理后图像
     * @param imageGuid 图像唯一标识
     * @return 处理后图像，如果不存在则返回空图像
     */
    QImage getProcessedImage(const QString &imageGuid) const;

    /**
     * @brief 获取当前应显示的图像（优先处理后图像）
     * @param imageGuid 图像唯一标识
     * @return 应显示的图像
     */
    QImage getDisplayImage(const QString &imageGuid) const;

    /**
     * @brief 设置原始图像（支持不存在时创建）
     * @param imageGuid 图像唯一标识
     * @param originalImage 原始图像
     * @param createIfMissing 若缓存中不存在该图像，则创建新项
     */
    void setOriginalImage(const QString &imageGuid, const QImage &originalImage, bool createIfMissing = true);

    /**
     * @brief 设置处理后图像
     * @param imageGuid 图像唯一标识
     * @param processedImage 处理后图像
     */
    void setProcessedImage(const QString &imageGuid, const QImage &processedImage);

    /**
     * @brief 获取长度单位转换比例
     * @param imageGuid 图像唯一标识
     * @return 长度转换比例
     */
    double getLengthRatio(const QString &imageGuid) const;

    /**
     * @brief 设置长度单位转换比例
     * @param imageGuid 图像唯一标识
     * @param ratio 长度转换比例
     */
    void setLengthRatio(const QString &imageGuid, double ratio);

    /**
     * @brief 获取时间单位转换比例
     * @param imageGuid 图像唯一标识
     * @return 时间转换比例
     */
    double getTimeRatio(const QString &imageGuid) const;

    /**
     * @brief 设置时间单位转换比例
     * @param imageGuid 图像唯一标识
     * @param ratio 时间转换比例
     */
    void setTimeRatio(const QString &imageGuid, double ratio);

    /**
     * @brief 获取波长单位转换比例
     * @param imageGuid 图像唯一标识
     * @return 波长转换比例
     */
    double getWavelengthRatio(const QString &imageGuid) const;

    /**
     * @brief 设置波长单位转换比例
     * @param imageGuid 图像唯一标识
     * @param ratio 波长转换比例
     */
    void setWavelengthRatio(const QString &imageGuid, double ratio);

    /**
     * @brief 获取长度单位字符串
     * @param imageGuid 图像唯一标识
     * @return 长度单位字符串
     */
    QString getLengthUnit(const QString &imageGuid) const;

    /**
     * @brief 设置长度单位字符串
     * @param imageGuid 图像唯一标识
     * @param unit 长度单位字符串
     */
    void setLengthUnit(const QString &imageGuid, const QString &unit);

    /**
     * @brief 获取时间单位字符串
     * @param imageGuid 图像唯一标识
     * @return 时间单位字符串
     */
    QString getTimeUnit(const QString &imageGuid) const;

    /**
     * @brief 设置时间单位字符串
     * @param imageGuid 图像唯一标识
     * @param unit 时间单位字符串
     */
    void setTimeUnit(const QString &imageGuid, const QString &unit);

    /**
     * @brief 获取波长单位字符串
     * @param imageGuid 图像唯一标识
     * @return 波长单位字符串
     */
    QString getWavelengthUnit(const QString &imageGuid) const;

    /**
     * @brief 设置波长单位字符串
     * @param imageGuid 图像唯一标识
     * @param unit 波长单位字符串
     */
    void setWavelengthUnit(const QString &imageGuid, const QString &unit);

    /**
     * @brief 获取X轴单位类型
     * @param imageGuid 图像唯一标识
     * @return X轴单位类型（整数表示）
     */
    int getXAxisUnit(const QString &imageGuid) const;

    /**
     * @brief 设置X轴单位类型
     * @param imageGuid 图像唯一标识
     * @param unit X轴单位类型（整数表示）
     */
    void setXAxisUnit(const QString &imageGuid, int unit);

    /**
     * @brief 获取Y轴单位类型
     * @param imageGuid 图像唯一标识
     * @return Y轴单位类型（整数表示）
     */
    int getYAxisUnit(const QString &imageGuid) const;

    /**
     * @brief 设置Y轴单位类型
     * @param imageGuid 图像唯一标识
     * @param unit Y轴单位类型（整数表示）
     */
    void setYAxisUnit(const QString &imageGuid, int unit);

    /**
     * @brief 保存图像及所有参数的统一接口
     * @param imageGuid 图像唯一标识
     * @param savePath 保存路径
     * @return 是否保存成功
     */
    bool saveImageWithParams(const QString &imageGuid, const QString &savePath);

    /**
     * @brief 从缓存中移除图像
     * @param imageGuid 图像唯一标识
     * @return 是否成功移除
     */
    bool removeImageFromCache(const QString &imageGuid);

    /**
     * @brief 清除所有缓存
     */
    void clearCache();

    /**
     * @brief 检查图像是否存在于缓存中
     * @param imageGuid 图像唯一标识
     * @return 是否存在
     */
    bool containsImage(const QString &imageGuid) const;

    /**
     * @brief 获取所有缓存的图像GUID列表
     * @return 图像GUID列表
     */
    QStringList getAllImageGuids() const;



    /**
     * @brief 添加一个处理参数到处理列表
     * @param imageGuid 图像唯一标识
     * @param params 处理参数配置，必须包含algorithmName
     * @param enableUndo 是否启用撤销功能，默认为true
     * @return 添加的参数在列表中的索引位置，如果添加失败则返回-1
     */
    int addProcessingParam(const QString &imageGuid, const QVariantMap &params, bool enableUndo = true);

    /**
     * @brief 移除处理参数列表中的一个参数
     * @param imageGuid 图像唯一标识
     * @param index 参数在列表中的索引位置
     * @param enableUndo 是否启用撤销功能，默认为true
     * @return 是否移除成功
     */
    bool removeProcessingParam(const QString &imageGuid, int index, bool enableUndo = true);

    /**
     * @brief 清除所有处理参数
     * @param imageGuid 图像唯一标识
     * @param enableUndo 是否启用撤销功能，默认为true
     */
    void clearProcessingParams(const QString &imageGuid, bool enableUndo = true);

    /**
     * @brief 获取所有处理参数
     * @param imageGuid 图像唯一标识
     * @return 按处理顺序排列的所有参数列表
     */
    QList<QVariantMap> getAllProcessingParams(const QString &imageGuid) const;

    /**
     * @brief 获取特定索引位置的处理参数
     * @param imageGuid 图像唯一标识
     * @param index 参数在列表中的索引位置
     * @return 索引位置的处理参数，如果索引无效则返回空QVariantMap
     */
    QVariantMap getProcessingParam(const QString &imageGuid, int index) const;


signals:
    /**
     * @brief 当图像添加到缓存时发出
     * @param imageGuid 图像唯一标识
     */
    void imageAdded(const QString &imageGuid);

    /**
     * @brief 当图像从缓存中移除时发出
     * @param imageGuid 图像唯一标识
     */
    void imageRemoved(const QString &imageGuid);

    /**
     * @brief 当图像更新时发出
     * @param imageGuid 图像唯一标识
     */
    void imageUpdated(const QString &imageGuid);



public:
    /**
     * @brief 设置默认保存路径
     * @param path 默认保存路径
     */
    void setDefaultSavePath(const QString &path);

    /**
     * @brief 获取默认保存路径
     * @return 默认保存路径
     */
    QString getDefaultSavePath() const;

    /**
     * @brief 设置默认保存格式
     * @param format 默认保存格式
     */
    void setDefaultSaveFormat(const QString &format);

    /**
     * @brief 获取默认保存格式
     * @return 默认保存格式
     */
    QString getDefaultSaveFormat() const;

private:
    // 图像加载器和保存器
    ImageLoader m_imageLoader;       // 用于加载图像的工具
    ImageSaver m_imageSaver;         // 用于保存图像的工具

    // 图像缓存映射表，key为GUID，value为缓存项
    QMap<QString, ImageCacheItem> m_imageCache;


};

#endif // IMAGECACHEMANAGER_H
